package yixaun.tim.service.impl;

import lombok.NonNull;
import org.springframework.util.CollectionUtils;
import yixaun.tim.bean.account.TimFriend;
import yixaun.tim.bean.relation.*;
import yixaun.tim.common.TimException;
import yixaun.tim.bean.relation.AddFriendSourceEnum;
import yixaun.tim.bean.relation.AddFriendTypeEnum;
import yixaun.tim.bean.relation.DeleteFriendTypeEnum;
import yixaun.tim.service.TimRelationService;
import yixaun.tim.service.TimService;
import yixaun.tim.util.JsonUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author pengshiqing
 * @Date: 2019/6/24
 * @Description:
 */
public class TimRelationServiceImpl implements TimRelationService {

    private TimService timService;

    public TimRelationServiceImpl(TimService timService) {
        this.timService = timService;
    }

    private final String ADD_SOURCE_TYPE_PREFIX = "AddSource_Type_";

    /**
     * 添加好友 添加好友，支持批量添加好友。
     * @param identifier    需要添加好友的
     * @param friends       被添加的
     * @param source  好友来源,自动补全AddSource_Type_XXX,所以仅输入"XXX"即可
     * @param addFriendTypeEnum 好友添加方式,为 null 则双向添加好友( Add_Type_Both )
     */
    @Override
    public AddRelationVo addFriends(@NonNull String identifier, @NonNull List<String> friends, @NonNull String source, AddFriendTypeEnum addFriendTypeEnum) throws TimException {
        if (CollectionUtils.isEmpty(friends)) {
            throw new TimException(0,"friends 不能为空");
        }
        if (addFriendTypeEnum == null){
            addFriendTypeEnum = AddFriendTypeEnum.Add_Type_Both ;
        }

        String api = "v4/sns/friend_add";

        Map<String, Object> body = new HashMap<>();
        body.put("From_Account", identifier);
        body.put("AddType", addFriendTypeEnum.getInfo());

        List<AddFriendItem> list = new ArrayList<>();
        for (String friend : friends) {
            AddFriendItem item = new AddFriendItem(friend, ADD_SOURCE_TYPE_PREFIX + source ) ;
            list.add(item);
        }
        body.put("AddFriendItem",list);
        return JsonUtils.fromJson(this.timService.post(api, body), AddRelationVo.class);
    }
    @Override
    public AddRelationVo addFriends(@NonNull String identifier, @NonNull List<String> friends, @NonNull AddFriendSourceEnum addFriendSourceEnum, AddFriendTypeEnum addFriendTypeEnum) throws TimException {
        return addFriends(identifier,friends, addFriendSourceEnum.getInfo(), addFriendTypeEnum);
    }

    @Override
    public AddRelationVo addFriends(@NonNull String identifier, @NonNull List<String> friends, @NonNull AddFriendSourceEnum addFriendSourceEnum) throws TimException {
        return addFriends(identifier,friends, addFriendSourceEnum, AddFriendTypeEnum.Add_Type_Both);
    }


    /**
     * 批量导入单向好友
     *
     * @param identifier   需要导入好友的 Identifier
     * @param friends      被添加的 Identifier 集合
     * @param source 好友来源,自动补全AddSource_Type_XXX,所以仅输入"XXX"即可
     * @return
     */
    @Override
    public AddRelationVo importFriends(@NonNull String identifier, @NonNull List<String> friends, @NonNull String source) throws TimException {
        if (CollectionUtils.isEmpty(friends)) {
            throw new TimException(0,"friends 不能为空");
        }

        List<TimFriend> list = new ArrayList<>();
        TimFriend timFriend = null;

        for (String friend : friends) {
            timFriend = new TimFriend(friend, ADD_SOURCE_TYPE_PREFIX + source);
            list.add(timFriend);
        }

        return this.importFriends(identifier, list);
    }

    /**
     * 导入好友
     * <p>
     * 支持批量导入单向好友；
     * 往同一个用户导入好友时建议采用批量导入的方式，避免并发写导致的写冲突。
     * <p>
     * API Doc : https://cloud.tencent.com/document/product/269/8301
     *
     * @param identifier 需要导入好友的 <b>Identifier</b>
     * @param friends    被添加的 <b>TimFriend</b> 集合
     * @return
     */
    @Override
    public AddRelationVo importFriends(@NonNull String identifier, @NonNull List<TimFriend> friends) throws TimException {
        String api = "v4/sns/friend_import";

        Map<String, Object> body = new HashMap<>();

        body.put("From_Account", identifier);
        body.put("AddFriendItem", friends);

        return JsonUtils.fromJson(this.timService.post(api, body), AddRelationVo.class);
    }

    /**
     * 更新好友
     * <p>
     * 支持批量更新同一用户的多个好友的关系链数据。
     * 更新一个用户多个好友时，建议采用批量方式，避免并发写导致的写冲突。
     * <p>
     * API Doc : https://cloud.tencent.com/document/product/269/12525
     *
     * @param identifier
     * @param updateItems
     * @return
     * @throws TimException
     */
    @Override
    public UpdateFriendsVo updateFriends(@NonNull String identifier, @NonNull List<UpdateItem> updateItems) throws TimException {
        String api = "v4/sns/friend_update";

        if (CollectionUtils.isEmpty(updateItems)) {
            throw new RuntimeException("friends 不能为空");
        }
        Map<String, Object> body = new HashMap<>(2);

        body.put("From_Account", identifier);
        body.put("UpdateItem", updateItems);

        return JsonUtils.fromJson(this.timService.post(api, body), UpdateFriendsVo.class);
    }

    /**
     * 删除好友
     * <p>
     * 删除好友，支持单向删除好友和双向删除好友。
     * <p>
     * API Doc : https://cloud.tencent.com/document/product/269/1644
     *
     * @param identifier 账号 <b>Identifier</b>
     * @param friends    删除的好友列表 <b>Identifier</b> 集合
     * @param deleteType 删除方式,为 <b>null</b> 则双向删除( Delete_Type_Both )
     * @return
     */
    @Override
    public DeleteFriendsVo deleteFriend(@NonNull String identifier, @NonNull List<String> friends, DeleteFriendTypeEnum deleteType) throws TimException {
        if (CollectionUtils.isEmpty(friends)) {
            throw new RuntimeException("friends can't be empty");
        }

        String api = "v4/sns/friend_delete";

        Map<String, Object> body = new HashMap<>();
        body.put("From_Account", identifier);
        body.put("To_Account", friends);

        if (deleteType == null) {
            deleteType = DeleteFriendTypeEnum.Delete_Type_Both;
        }

        body.put("DeleteType", deleteType.getInfo());

        return JsonUtils.fromJson(this.timService.post(api, body), DeleteFriendsVo.class);
    }

    @Override
    public DeleteFriendsVo deleteFriend(@NonNull String identifier, @NonNull List<String> friends) throws TimException {
        return deleteFriend(identifier,friends,null);
    }


}
